using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Windows.Input;
using System.Diagnostics.Contracts;
using System.Windows;

namespace PEM
{
    internal partial class NotesViewModel // TOFIX: make commands disposable?
    {
        #region Commands

        public class AddNoteCommand : ICommand
        {
            #region Constructor

            public AddNoteCommand(NotesViewModel model)
            {
                Contract.Requires(model != null);

                _model = model;

                _model.SuiteOpened += OnSuiteStateChanged;
                _model.SuiteClosed += OnSuiteStateChanged;
                _model.SuiteCreated += OnSuiteStateChanged;
                _model.SuiteDeleted += OnSuiteStateChanged;
            }

            #endregion // Constructor

            #region ICommand Members

            public bool CanExecute(object parameter)
            {
                return _model.Suite != null;
            }

            public event System.EventHandler CanExecuteChanged;

            public void Execute(object parameter)
            {
                _model.AddNote();
            }

            #endregion

            #region Event Handlers

            private void OnSuiteStateChanged(ViewModelBase sender)
            {
                if (CanExecuteChanged != null)
                {
                    CanExecuteChanged(this, EventArgs.Empty);
                }
            }

            #endregion // Event Handlers

            #region Fields

            private NotesViewModel _model;

            #endregion // Fields
        }

        public class RemoveNoteCommand : ICommand
        {
            #region Constructor

            public RemoveNoteCommand(NotesViewModel model)
            {
                Contract.Requires(model != null);

                _model = model;

                _model.SuiteOpened += OnSuiteStateChanged; // TOFIX: do we really need in all this events?
                _model.SuiteClosed += OnSuiteStateChanged;
                _model.SuiteCreated += OnSuiteStateChanged;
                _model.SuiteDeleted += OnSuiteStateChanged;
                _model.NoteSelected += OnSuiteStateChanged;
            }

            #endregion // Constructor

            #region ICommand Members

            public bool CanExecute(object parameter)
            {
                // TOFIX: selected note
                return _model.SelectedNote != null;
            }

            public event System.EventHandler CanExecuteChanged;

            public void Execute(object parameter)
            {
                _model.RemoveNote();
            }

            #endregion

            #region Event Handlers

            private void OnSuiteStateChanged(ViewModelBase sender)
            {
                if (CanExecuteChanged != null)
                {
                    CanExecuteChanged(this, EventArgs.Empty);
                }
            }

            #endregion // Event Handlers

            #region Fields

            private NotesViewModel _model;

            #endregion // Fields
        }

        public class EditNoteCommand : ICommand
        {
            #region Constructor

            public EditNoteCommand(NotesViewModel model)
            {
                Contract.Requires(model != null);

                _model = model;

                _model.SuiteOpened += OnSuiteStateChanged;
                _model.SuiteClosed += OnSuiteStateChanged;
                _model.SuiteCreated += OnSuiteStateChanged;
                _model.SuiteDeleted += OnSuiteStateChanged;
            }

            #endregion // Constructor

            #region ICommand Members

            public bool CanExecute(object parameter)
            {
                // TOFIX: selected note
                return _model.SelectedNote != null;
            }

            public event System.EventHandler CanExecuteChanged;

            public void Execute(object parameter)
            {
                _model.EditNote();
            }

            #endregion

            #region Event Handlers

            private void OnSuiteStateChanged(ViewModelBase sender)
            {
                if (CanExecuteChanged != null)
                {
                    CanExecuteChanged(this, EventArgs.Empty);
                }
            }

            #endregion // Event Handlers

            #region Fields

            private NotesViewModel _model;

            #endregion // Fields
        }

        #endregion // Commands

        #region Commands Collection

        public class CommandsCollection
        {
            #region Properties

            public AddNoteCommand AddNote
            {
                get;
                private set;
            }

            public RemoveNoteCommand RemoveNote
            {
                get;
                private set;
            }

            public EditNoteCommand EditNote
            {
                get;
                private set;
            }

            #endregion // Properties

            #region Constructor

            public CommandsCollection(NotesViewModel host)
            {
                Contract.Requires(host != null);

                AddNote = new AddNoteCommand(host);
                RemoveNote = new RemoveNoteCommand(host);
                EditNote = new EditNoteCommand(host);
            }

            #endregion // Constructor
        }

        #endregion // Commands Collection

        private void AddNote()
        {
            Contract.Assert(Suite != null);

            if (_createEditNoteDlg.ShowDialog(_parentWindow))
            {
                Suite.Notes.Add(_createEditNoteDlg.NoteTitle, _createEditNoteDlg.NoteText);
            }
        }

        private void RemoveNote()
        {
            Contract.Assert(Suite != null);

            if (SelectedNote != null)
            {
                if (MessageBox.Show("Are you really wish to delete this note?", "Confirmation", MessageBoxButton.YesNo) == MessageBoxResult.Yes)
                {
                    Suite.Notes.Remove(SelectedNote.ID);
                }
            }
        }

        private void EditNote()
        {
            Contract.Assert(Suite != null);

            if (SelectedNote != null)
            {
                if (_createEditNoteDlg.ShowDialog(_parentWindow, SelectedNote))
                {
                    SelectedNote.Title = _createEditNoteDlg.NoteTitle;
                    SelectedNote.Text = _createEditNoteDlg.NoteText;
                }
            }
        }
    }
}
